﻿using PostSharp.Aspects;
using Shared.Cache;
using Shared.DI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Services.Aspects
{
    [Serializable]
    public abstract class CacheActionAttribute : MethodInterceptionAspect
    {
        public string Name { get; set; }

        [NonSerialized]
        protected ICacheStorage cacheStorage;
        public override void RuntimeInitialize(MethodBase method)
        {
            cacheStorage = DependencyContext.CurrentContainer.Resolve<ICacheStorage>();
        }

        protected string GetCacheKey(MethodInterceptionArgs args)
        {
            string rootKey;
            if (!string.IsNullOrEmpty(Name))
                rootKey = Name;
            else
            {
                var cacheKeyAttribute = args.Instance.GetType().GetCustomAttribute<CacheNameAttribute>();
                if (cacheKeyAttribute != null)
                    rootKey = cacheKeyAttribute.Name;
                else
                    rootKey = args.Instance.GetType().Name;
            }

            return string.Format("{0}{1}", rootKey, GetArgumentsCacheKey(args.Arguments));
        }

        protected string GetArgumentsCacheKey(Arguments arguments)
        {
            StringBuilder key = new StringBuilder();
            for (int i = 0; i < arguments.Count; i++)
                if (arguments[i].GetType().IsPrimitive || arguments[i].GetType() == typeof(String))
                {
                    key.Append("_");
                    key.Append(arguments[i]);
                }

            return key.ToString();
        }
    }  
}
